package com.btpj.hospital_server.service;

import com.btpj.hospital_server.entity.LogAccountLogin;
import com.btpj.hospital_server.entity.PowerAccount;
import com.btpj.hospital_server.mapper.PowerAccountMapper;
import com.btpj.hospital_server.mapper.PowerRoleMapper;
import com.btpj.hospital_server.utils.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 用户管理Service
 *
 * @author BTPJ  2020/8/24
 */
@Service
public class PowerAccountService implements UserDetailsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PowerAccountService.class);

    @Resource
    PowerAccountMapper powerAccountMapper;

    @Resource
    PowerRoleMapper powerRoleMapper;

    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    JwtTokenUtil jwtTokenUtil;

    @Resource
    LogAccountLoginService logAccountLoginService;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        PowerAccount powerAccount = powerAccountMapper.getAccountByName(s);
        if (powerAccount == null) {
            return null;
        }
        powerAccount.setPowerRoles(powerRoleMapper.getRolesByAccountId(powerAccount.getId()));
        return powerAccount;
    }

    /**
     * 登录
     *
     * @param name     用户名
     * @param password 密码
     * @return 是否登录成功
     */
    public String login(String name, String password) {
        String jwtToken = null;

        // 客户端传递账号和加密后的密码
        try {
            PowerAccount powerAccount = (PowerAccount) loadUserByUsername(name);
            // 密码不匹配
            if (!passwordEncoder.matches(password, powerAccount.getPassword())) {
                throw new BadCredentialsException("密码错误");
            }

            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(powerAccount, null, powerAccount.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            powerAccount.setGmtModified(new Date());
            jwtToken = tokenHead + " " + jwtTokenUtil.generateToken(name);

            // 添加登录日志
            LogAccountLogin logAccountLogin = new LogAccountLogin();
            logAccountLogin.setAccountId(powerAccount.getId());
            logAccountLogin.setAccountName(powerAccount.getName());
            logAccountLogin.setGmtCreate(new Date());
            logAccountLogin.setGmtModified(new Date());
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                logAccountLogin.setIpAddress(request.getRemoteAddr());
            }
            logAccountLoginService.addLoginLog(logAccountLogin);
        } catch (Exception e) {
            LOGGER.error("用户 :{} , 登录失败 :{}", name, e.getMessage());
        }
        return jwtToken;
    }

    /**
     * 获取登录的用户信息
     *
     * @return 登录的用户信息
     */
    public PowerAccount getUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return null;
        }

        return (PowerAccount) authentication.getPrincipal();
    }

    /**
     * 检查密码是否正确
     *
     * @param password 密码
     * @return 检查密码是否正确
     */
    public boolean checkPassword(String password) {
        PowerAccount powerAccount = getUserInfo();
        return passwordEncoder.matches(password, powerAccount.getPassword());
    }

    /**
     * 修改密码
     *
     * @param newPassword 要修改的新密码
     * @return 是否修改成功
     */
    public boolean changePwd(String newPassword) {
        PowerAccount powerAccount = getUserInfo();
        powerAccount.setPassword(passwordEncoder.encode(newPassword));
        powerAccount.setGmtModified(new Date());
        return powerAccountMapper.updateByPrimaryKeySelective(powerAccount) > 0;
    }
}
